package com.cjd.view.audio;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.cjd.common.R;
import com.cjd.common.utils.LogUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @Author chenjidong
 * @email 374122600@qq.com
 * created 2019/7/31
 * description 防抖音 左右拖拽区域  滑动裁剪音频
 */
public class AudioSpectrumViewGroup extends ViewGroup implements View.OnTouchListener {
    private int moveX, moveY, downX, downY, leftMoveX, rightMoveX;
    private View dragView;
    private int indicatorWidth;
    AudioSpectrumView audioSpectrumView;
    private FrameLayout leftIndicator, rightIndicator;
    private int duration = 10 * 1000;
    ValueAnimator progressValueAnimator;

    private OnDragProgressListener onDragProgressListener;
    private boolean isPause = false;
    private ObjectAnimator leftObjectAnimator, rightObjectAnimator;


    public void setOnDragProgressListener(OnDragProgressListener onDragProgressListener) {
        this.onDragProgressListener = onDragProgressListener;
    }

    public AudioSpectrumViewGroup(Context context) {
        super(context);
        init();
    }

    public AudioSpectrumViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public AudioSpectrumViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        indicatorWidth = dp2px(40);
        audioSpectrumView = new AudioSpectrumView(getContext());

        addView(audioSpectrumView);

        final int iconSize = indicatorWidth / 3 * 2;
        leftIndicator = new FrameLayout(getContext());
        leftIndicator.setTag("left");

        ImageView ivLeft = new ImageView(getContext());
        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(iconSize, iconSize);
        lp.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT;
        ivLeft.setImageResource(R.drawable.base_ic_right_arrow_theme);

        leftIndicator.addView(ivLeft, lp);

        leftIndicator.setBackgroundColor(getResources().getColor(R.color.audio_indicator_bg));


        addView(leftIndicator);

        rightIndicator = new FrameLayout(getContext());
        rightIndicator.setTag("right");

        rightIndicator.setBackgroundColor(getResources().getColor(R.color.audio_indicator_bg));

        ImageView ivRight = new ImageView(getContext());
        FrameLayout.LayoutParams lp1 = new FrameLayout.LayoutParams(iconSize, iconSize);
        lp1.gravity = Gravity.CENTER_VERTICAL;
        ivRight.setImageResource(R.drawable.base_ic_left_arrow_theme);

        rightIndicator.addView(ivRight, lp1);

        addView(rightIndicator);

        progressValueAnimator = ValueAnimator.ofInt(0, 100);
        progressValueAnimator.setDuration(duration);
        progressValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int progress = (int) animation.getAnimatedValue();
                audioSpectrumView.setCurrentProgress(progress);
            }
        });
//        progressValueAnimator.start();

        leftObjectAnimator = ObjectAnimator.ofFloat(ivLeft, "translationX", 0, -iconSize, 0);
        leftObjectAnimator.setRepeatCount(-1);
        leftObjectAnimator.setDuration(1000);
        leftObjectAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        leftObjectAnimator.start();

        rightObjectAnimator = ObjectAnimator.ofFloat(ivRight, "translationX", 0, iconSize, 0);
        rightObjectAnimator.setRepeatCount(-1);
        rightObjectAnimator.setDuration(1000);
        rightObjectAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        rightObjectAnimator.start();

    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (leftObjectAnimator != null)
            leftObjectAnimator.cancel();
        if (rightObjectAnimator != null)
            rightObjectAnimator.cancel();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        measureChildren(widthMeasureSpec, heightMeasureSpec);

        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        LogUtils.d("--->onMeasure:" + width + " height:" + height);


        // 自定义view padding
        for (int i = 0; i < getChildCount(); i++) {
            View view = getChildAt(i);
            if (view instanceof AudioSpectrumView) {
                int mode = MeasureSpec.AT_MOST;
                int widthChildMeasureSpec = MeasureSpec.makeMeasureSpec(width - indicatorWidth * 2, mode);
                int heightChildMeasureSpec = MeasureSpec.makeMeasureSpec(height, mode);
                view.measure(widthChildMeasureSpec, heightChildMeasureSpec);
            } else {
                view.measure(widthMeasureSpec, heightMeasureSpec);
            }
        }

//        measureChildren(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        LogUtils.d("--->onLayout l:" + l + " t:" + t + " r:" + " b:" + b + " rightMoveX:" + rightMoveX);
        l = 0;
        t = 0;
        r = getWidth();
        b = getHeight();
        audioSpectrumView.layout(l + indicatorWidth, t, r - indicatorWidth, b);


        leftIndicator.layout(0, t, leftMoveX <= 0 ? indicatorWidth : leftMoveX, b);
        leftIndicator.setOnTouchListener(this);

        rightIndicator.layout(rightMoveX <= 0 ? (r - indicatorWidth) : rightMoveX, t, r, b);
        rightIndicator.setOnTouchListener(this);

    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        LogUtils.d("--->dispatchDraw");
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                dragView = v;

                stopAnimation();
                break;
        }

        return false;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        getParent().requestDisallowInterceptTouchEvent(true);
        return super.dispatchTouchEvent(ev);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                downX = (int) event.getX();
                downY = (int) event.getY();
                if (dragView == null && downX >= audioSpectrumView.getStartWidth() && downX <= audioSpectrumView.getEndWidth()) {
                    isPause = !isPause;
                    pauseAnimation(isPause);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                moveX = (int) event.getX();
                moveY = (int) event.getY();
                if (dragView != null) {
                    refreshView();
                }

                break;
            case MotionEvent.ACTION_UP:
                onActionCancel();
                break;
            case MotionEvent.ACTION_CANCEL:
                onActionCancel();
                break;
        }
        return true;
    }

    private void onActionCancel() {
        if (dragView != null) {
            if (onDragProgressListener != null)
                onDragProgressListener.onDrawFinish(audioSpectrumView.getStartProgress(), audioSpectrumView.getEndProgress());
        }
        dragView = null;

        invalidate();
    }

    private void pauseAnimation(boolean isPause) {
        if (isPause) {
            setAudioSpectrumProgressPlaying(false);
            if (onDragProgressListener != null)
                onDragProgressListener.onPause(true);
        } else {
            setAudioSpectrumProgressPlaying(true);
            if (onDragProgressListener != null)
                onDragProgressListener.onPause(false);
        }
    }

    public void stopAnimation() {
        setAudioSpectrumProgressPlaying(false);
    }

    public void startAnimation() {
        setAudioSpectrumProgressPlaying(true);
    }

    public boolean getAudioSpectrumProgressPlaying() {
        return audioSpectrumView.isPlaying();
    }

    public void setAudioSpectrumProgressPlaying(boolean isPlaying) {
        audioSpectrumView.setPlaying(isPlaying);
        if (isPlaying) {
            setPause(false);
        } else
            setPause(true);
    }

    public void setCurrentProgress(int milliseconds) {
        int single = duration / 100;
        audioSpectrumView.setCurrentProgress(milliseconds / single);
    }

    private void refreshView() {
        if (dragView == null)
            return;
        if (TextUtils.equals(dragView.getTag().toString(), leftIndicator.getTag().toString())) {
            int r = moveX + indicatorWidth;//扩大触摸位置，避免失去焦点
            leftMoveX = r;

            if (r < indicatorWidth)
                r = indicatorWidth;

            if (r > rightIndicator.getLeft())
                r = rightIndicator.getLeft();

            dragView.layout(0, 0, r, getHeight());

            int progress = 0;
            if (dragView.getRight() > indicatorWidth) {
                int realX = dragView.getRight() - indicatorWidth;
                // TODO: 2019/8/2 精度bug 计算结果 最右边 最终为 99.99999 音频不能裁剪0秒
                progress = (int) (realX / ((getWidth() - indicatorWidth * 2) / 100f));
                if (progress >= 99.99)
                    progress = 100;
            }

            audioSpectrumView.setStartProgress(progress);

        } else if (TextUtils.equals(dragView.getTag().toString(), rightIndicator.getTag().toString())) {
            int l = moveX - indicatorWidth;
            rightMoveX = l;
            if (l > (getWidth() - indicatorWidth))
                l = getWidth() - indicatorWidth;
            if (l <= leftIndicator.getRight()) {
                l = leftIndicator.getRight();
            }

            dragView.layout(l, 0, getWidth(), getHeight());

            int progress;
            if (dragView.getLeft() == (getWidth() - indicatorWidth))
                progress = 100;
            else {
                int realX = dragView.getLeft() - indicatorWidth;
                progress = (int) (realX / ((getWidth() - indicatorWidth * 2) / 100f));
            }
            audioSpectrumView.setEndProgress(progress);
        }

        if (onDragProgressListener != null)
            onDragProgressListener.onDrawProgress(audioSpectrumView.getStartProgress(), audioSpectrumView.getEndProgress());

        invalidate();
    }

    public void setPause(boolean pause) {
        isPause = pause;
    }

    public int getDuration() {
        return duration;
    }

    public void setDuration(int duration) {
        this.duration = duration;
    }

    public int getStartDuration() {
        return duration / 100 * audioSpectrumView.getStartProgress();
    }

    public int getEndDuration() {
        return duration / 100 * audioSpectrumView.getEndProgress();
    }

    public String getStartTimeStr() {
        int single = duration / 100;
        int startSecond = single * audioSpectrumView.getStartProgress() / 1000;
        return second2Str(startSecond);
    }

    public int getDurationSecond() {
        return getEndDuration() / 1000 - getStartDuration() / 1000;
    }

    public String getDurationSecondStr(int milliseconds) {
        return second2Str(milliseconds / 1000);
    }

    /**
     * 由于音频 最后一次position 有差异
     *
     * @param audioDurationMilliseconds
     * @return
     */
    private int accuracyConvert(int audioDurationMilliseconds) {
        float value = audioDurationMilliseconds / 1000F;
        BigDecimal bigDecimal = new BigDecimal(value).setScale(3, RoundingMode.HALF_UP);
        return bigDecimal.intValue() * 1000;
    }

    public String getEndTimeStr() {
        int single = duration / 100;
        int startSecond = single * audioSpectrumView.getEndProgress() / 1000;
        return second2Str(startSecond);
    }

    private String second2Str(int second) {
        int minute = second / 60;
        int remainingSecond = second % 60;

        String stringBuilder = (minute < 10 ? "0" + minute : minute) +
                ":" + (remainingSecond < 10 ? "0" + remainingSecond : remainingSecond);

        return stringBuilder;
    }

    private int dp2px(float dpValue) {
        float scale = getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    public interface OnDragProgressListener {

        void onDrawProgress(int startProgress, int endProgress);

        void onDrawFinish(int startProgress, int endProgress);

        void onPause(boolean isPause);
    }
}
